#!/usr/bin/python
# -*- coding: utf-8 -*-

"""     This program is free software; you can redistribute it and/or modify
#       it under the terms of the GNU General Public License as published by
#       the Free Software Foundation; either version 2 of the License, or
#       (at your option) any later version.
#
#       This program is distributed in the hope that it will be useful,
#       but WITHOUT ANY WARRANTY; without even the implied warranty of
#       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#       GNU General Public License for more details.
#
#       You should have received a copy of the GNU General Public License
#       along with this program; if not, write to the Free Software
#       Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
#       MA 02110-1301, USA.

"""

__author__ = "Evgeniy Frolov"
__email__ = "profisphantom@gmail.com"
__version__ = "2.0.1"

from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.schema import Column, ForeignKey, Table
from sqlalchemy.types import Integer, String, Date, BigInteger, Boolean, Float
from sqlalchemy.orm import relationship, backref, mapper

Base = declarative_base
Base = Base()


class BaseOperations(object):
    def __repr__(self):
        text = "<%s(" % self.__class__.__name__ + "'%s'"
        for i in self.columns:
            if i == self.columns[0]:
                values = (getattr(self,i),)
            else:
                values += (getattr(self,i),)
                text += ", '%s'"
        text += ")>"
        return text % values

    def raw_data(self):
        result = {}
        for i in self.columns:
            result[i] = getattr(self, i)
        return result


rt_association_table = Table('rtcodetable', Base.metadata,
    Column('guid', BigInteger, ForeignKey('repair_note.repairtype')),
    Column('rtcode', Integer, ForeignKey('repair_type.code'))
)


sp_association_table = Table('spcodetable', Base.metadata,
    Column('id', Integer, primary_key=True, autoincrement=True),
    Column('guid', BigInteger, ForeignKey('repair_note.otherspareparts')),
    Column('spcode', Integer, ForeignKey('spare_parts.id')),
    Column('quantity', Integer, nullable=False),
)

class SPCodeTable(object):
    pass

mapper(SPCodeTable, sp_association_table)


#class SPCodeTable(Base, BaseOperations):
#    __table__ = 'spcodetable'
#
#    columns = []
#
#    id = Column(Integer, primary_key=True, autoincrement=True)
#    guid = Column(BigInteger, nullable=False)
#    spcode = Column(BigInteger, nullable=False)
#    quantity = Column(Float, nullable=False)


class RepairNote(Base, BaseOperations):
    __tablename__ = 'repair_note'

    columns = ["id", "repairnumber", "cooler", "repairdate", "brand", "dispatchdate",
        "dispatchnote", "specialnote", "repairtype", "transactiontype", "otherspareparts"]

    id = Column(Integer, primary_key=True, autoincrement=True)
    repairnumber = Column(String(11), unique=True)
    cooler = Column(Integer, ForeignKey('cooler_receipt.id'))
    repairdate = Column(Date)
    brand = Column(String(50))
    dispatchdate = Column(Date)
    dispatchnote = Column(String(15))
    specialnote = Column(String(255))
    repairtype = Column(BigInteger)
    transactiontype = Column(Integer)
    otherspareparts = Column(BigInteger)

    cooler_receipt = relationship('CoolerReceipt', backref=backref('repair_note',
        uselist=False))
    repair_types = relationship("RepairType", secondary=rt_association_table)
    other_spare_parts = relationship("SpareParts", secondary=sp_association_table)

    def __init__(self, repairnumber, cooler, repairdate, brand, dispatchdate,
        dispatchnote, specialnote, repairtype, transactiontype, otherspareparts):
        self.repairnumber = repairnumber
        self.cooler = cooler
        self.repairdate = repairdate
        self.brand = brand
        self.dispatchdate = dispatchdate
        self.dispatchnote = dispatchnote
        self.specialnote = specialnote
        self.repairtype = repairtype
        self.transactiontype = transactiontype
        self.otherspareparts = otherspareparts


class RepairType(Base, BaseOperations):
    __tablename__ = 'repair_type'

    columns = []

    code = Column(Integer, primary_key=True, autoincrement=True)
    repairType = Column(String(150), nullable=False)
    repairTypeRus = Column(String(150), nullable=False)
    SparePartsConsumption = Column(BigInteger, nullable=False)
    model = Column(Integer, nullable=False)
    RepairTypePrice = Column(Float, nullable=False)
    SparePartsPrice = Column(Float, nullable=False)
    currency = Column(Integer, nullable=False)


class CoolerReceipt(Base, BaseOperations):
    __tablename__ = 'cooler_receipt'

    columns = ['id', 'customer', 'destination', 'model', 'snumber', 'inumber',
        'receipt_date_iso']

    id = Column(Integer, primary_key=True, autoincrement=True)
    customer = Column(Integer)
    destination = Column(Integer, ForeignKey('destination.id'))
    model = Column(Integer, ForeignKey('model.id'))
    snumber = Column(String(15))
    inumber = Column(String(20))
    receipt_date = Column(Date)

    destination_obj = relationship('Destination', backref=backref('cooler_receipt',
        uselist=False))
    model_obj = relationship('Model', backref=backref('cooler_receipt',
        uselist=False))

    def __init__(self, customer, destination, model, snumber, inumber, receipt_date):
        self.customer = customer
        self.destination = destination
        self.model = model
        self.snumber = snumber
        self.inumber = inumber
        self.receipt_date = receipt_date

    @property
    def receipt_date_iso(self):
        return self.receipt_date.isoformat()


class TransactionType(Base, BaseOperations):
    __tablename__ = 'transaction_type'

    columns = ['id', 'descr', 'operation']

    id = Column(Integer, primary_key=True, autoincrement=True)
    transactionType = Column(String(50), unique=True, index=True)
    transactionFormula = Column(Integer)

    def __init__(self, descr, operation):
        self.descr = descr
        self.operation = operation

    @property
    def descr(self):
        return self.transactionType

    @descr.setter
    def descr(self, value):
        self.transactionType = value

    @property
    def operation(self):
        return self.transactionType

    @operation.setter
    def operation(self, value):
        self.transactionType = int(value)


class Destination(Base, BaseOperations):
    __tablename__ = 'destination'

    columns = ['id', 'descr']

    id = Column(Integer, primary_key=True, autoincrement=True)
    daddr = Column(String(50), unique=True, index=True)

    def __init__(self, descr):
        self.descr = descr

    @property
    def descr(self):
        return self.daddr

    @descr.setter
    def descr(self, value):
        self.daddr = value


class Customer(Base, BaseOperations):
    __tablename__ = 'customer'

    columns = ['id', 'descr', 'group_id']

    id = Column(Integer, primary_key=True, autoincrement=True)
    name = Column(String(50), unique=True, index=True)
    group = Column(Integer, ForeignKey('customer_group.id'))
    group_obj = relationship('CustomerGroup')

    def __init__(self, descr, group_id):
        self.descr = descr
        self.group_id = group_id

    @property
    def descr(self):
        return self.name

    @descr.setter
    def descr(self, value):
        self.name = value

    @property
    def group_id(self):
        return self.group

    @group_id.setter
    def group_id(self, value):
        self.group = value


class CustomerGroup(Base, BaseOperations):
    __tablename__ = 'customer_group'

    columns = ['id', 'group']

    id = Column(Integer, primary_key=True, autoincrement=True)
    group = Column(String(50), unique=True, index=True)

    def __init__(self, group):
        self.group = group


class Unit(Base, BaseOperations):
    __tablename__ = "unit"

    columns = ['id', 'descr']

    id = Column(Integer, primary_key=True, autoincrement=True)
    descr = Column(String(5), nullable=False, unique=True, index=True)

    def __init__(self, descr):
        self.descr = descr


class Model(Base, BaseOperations):
    __tablename__ = "model"

    columns = ['id', 'descr']

    id = Column(Integer, primary_key=True, autoincrement=True)
    name = Column(String(25), nullable=False, unique=True, index=True)

    def __init__(self, descr):
        self.descr = descr

    @property
    def descr(self):
        return self.name

    @descr.setter
    def descr(self, value):
        self.name = value


models_association_table = Table('model_swap', Base.metadata,
    #Column('id', primary_key=True, autoincrement=True),
    Column('select_id', Integer, ForeignKey('spare_parts.model')),
    Column('model_id', Integer, ForeignKey('model.id'))
)


class SpareParts(Base, BaseOperations):
    __tablename__ = "spare_parts"

    columns = ['id', 'code', 'description', 'description_rus', 'unit_desc',\
               'integer', 'price', 'currency', 'safety_stock', 'planning_type',\
               'planning_condition', 'models']

    id = Column(Integer, primary_key=True, autoincrement=True)
    code = Column(BigInteger, unique=True, index=True)
    description = Column(String(150), nullable=False)
    unit = Column(Integer, ForeignKey('unit.id'), nullable=False)
    description_rus = Column(String(150), nullable=False)
    integer = Column(Boolean, nullable=False)
    price = Column(Float)
    currency = Column(Integer)
    model = Column(String(11), nullable=False)
    safety_stock = Column(Float, nullable=False)
    planning_type = Column(Integer, nullable=False)
    planning_condition = Column(Integer, nullable=False)

    unit_descriptor = relationship("Unit", uselist=False)
#    model_swap = relationship("ModelSwap")
    models = relationship("Model", secondary=models_association_table)


    def __init__(self, code, description, description_rus, integer, safety_stock,\
        planning_type, planning_condition, price=None, currency=None):
        self.code = code
        self.description = description
        self.description_rus = description_rus
        self.integer = integer
        self.safety_stock = safety_stock
        self.planning_type = planning_type
        self.planning_condition = planning_condition
        self.price = price
        self.currency = currency

    @property
    def unit_desc(self):
        return self.unit_descriptor.descr

#    @property
#    def models(self):
#        result = []
##        for i in self.model_swap:
##            result.append(i.model.descr)
#        result.append(self.model_swap.model.descr)
#        return result



#class ModelSwap(Base, BaseOperations):
#    __tablename__ = "model_swap"
#
#    columns = ['id', 'select_id', 'model_id']
#
#    id = Column(Integer, primary_key=True, autoincrement=True)
#    select_id = Column(String(10), ForeignKey('spare_parts.id'), nullable=False)
#    model_id = Column(Integer, ForeignKey('model.id'), nullable=False)
